package com.cleaningcloud.erp.service.impl;

import com.cleaningcloud.common.core.utils.DateUtils;
import com.cleaningcloud.common.core.utils.UniqueIdUtils;
import com.cleaningcloud.common.security.utils.CommunityTypeConversionUtils;
import com.cleaningcloud.common.security.utils.SecurityUtils;
import com.cleaningcloud.erp.domain.*;
import com.cleaningcloud.erp.domain.dto.ErpProcudeReturnDto;
import com.cleaningcloud.erp.domain.vo.ErpProcudeReturnVo;
import com.cleaningcloud.erp.domain.vo.ErpReturnDetailsVo;
import com.cleaningcloud.erp.mapper.*;
import com.cleaningcloud.erp.service.IErpProcudeReturnService;
import com.cleaningcloud.erp.utils.ProcureSaleUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 采购退换货Service业务层处理
 *
 * @author cleaningcloud
 * @date 2024-10-05
 */
@Service
public class ErpProcudeReturnServiceImpl implements IErpProcudeReturnService {
    @Autowired
    private ErpProcudeReturnMapper erpProcudeReturnMapper;

    @Autowired
    private ErpReturnDetailsMapper erpReturnDetailsMapper;

    @Autowired
    private ErpProcureMapper erpProcureMapper;

    @Autowired
    private ErpOutboundMapper erpOutboundMapper;

    @Autowired
    private ErpWarehousingMapper erpWarehousingMapper;

    @Autowired
    private ErpAccountsReceivableMapper erpAccountsReceivableMapper;

    @Autowired
    private ErpAccountsPayableMapper erpAccountsPayableMapper;

    /**
     * 新增应付账款单
     *
     * @param erpProcudeReturn
     * @param erpProcure
     * @return
     */
    private static ErpAccountsPayable getErpAccountsPayable(ErpProcudeReturnVo erpProcudeReturn, ErpProcure erpProcure, BigDecimal oddSumMoney) {
        ErpAccountsPayable erpAccountsPayable = new ErpAccountsPayable();
        erpAccountsPayable.setOddType(3);
        erpAccountsPayable.setOddNo(erpProcudeReturn.getProcudeReturnOdd());
        erpAccountsPayable.setBusinessId(erpProcure.getSupplierId());
        erpAccountsPayable.setOddDate(DateUtils.getNowDate());
        erpAccountsPayable.setOddStatus(0);
        erpAccountsPayable.setOddSumMoney(oddSumMoney);
        erpAccountsPayable.setFlag("Y");
        return erpAccountsPayable;
    }

    /**
     * 新增应收账款单
     *
     * @param erpProcudeReturn
     * @param erpProcure
     * @return
     */
    private static ErpAccountsReceivable getErpAccountsReceivable(ErpProcudeReturnVo erpProcudeReturn, ErpProcure erpProcure, BigDecimal oddSumMoney) {
        ErpAccountsReceivable erpAccountsReceivable = new ErpAccountsReceivable();
        erpAccountsReceivable.setOddType(2);
        erpAccountsReceivable.setOddNo(erpProcudeReturn.getProcudeReturnOdd());
        erpAccountsReceivable.setBusinessId(erpProcure.getSupplierId());
        erpAccountsReceivable.setOddDate(DateUtils.getNowDate());
        erpAccountsReceivable.setOddStatus(0);
        erpAccountsReceivable.setOddSumMoney(oddSumMoney);
        erpAccountsReceivable.setFlag("Y");
        return erpAccountsReceivable;
    }

    /**
     * 查询采购退换货
     *
     * @param procudeReturnId 采购退换货主键
     * @return 采购退换货
     */
    @Override
    public ErpProcudeReturnVo selectErpProcudeReturnByProcudeReturnId(Long procudeReturnId) {
        ErpProcudeReturnVo erpProcudeReturnVo = erpProcudeReturnMapper.selectErpProcudeReturnByProcudeReturnId(procudeReturnId);
        for (ErpReturnDetailsVo returnDetailsVo : erpProcudeReturnVo.getDetailsList()) {
            returnDetailsVo.setCommodityTypeName(CommunityTypeConversionUtils.conversion(returnDetailsVo.getCommodityTypeName()));
        }
        return erpProcudeReturnVo;
    }

    /**
     * 查询采购退换货列表
     *
     * @param erpProcudeReturn 采购退换货
     * @return 采购退换货
     */
    @Override
    public List<ErpProcudeReturnVo> selectErpProcudeReturnList(ErpProcudeReturnDto erpProcudeReturn) {
        return erpProcudeReturnMapper.selectErpProcudeReturnList(erpProcudeReturn);
    }

    /**
     * 新增采购退换货
     *
     * @param erpProcudeReturn 采购退换货
     * @return 结果
     */
    @Override
    @Transactional
    public int insertErpProcudeReturn(ErpProcudeReturnDto erpProcudeReturn) {
        erpProcudeReturn.setCreateTime(DateUtils.getNowDate());
        erpProcudeReturn.setFlag("Y");
        erpProcudeReturn.setCreateId(SecurityUtils.getUserId());
        erpProcudeReturn.setCreateName(SecurityUtils.getUsername());
        erpProcudeReturn.setApproveStatus(1);
        erpProcudeReturn.setProcudeReturnOdd("CGT" + UniqueIdUtils.generateUniqueId());
        erpProcudeReturnMapper.insertErpProcudeReturn(erpProcudeReturn);
        // 新增销售退还单明细
        batchReturnDetails(erpProcudeReturn);
        return 1;
    }

    /**
     * 修改采购退换货
     *
     * @param erpProcudeReturn 采购退换货
     * @return 结果
     */
    @Override
    @Transactional
    public int updateErpProcudeReturn(ErpProcudeReturnDto erpProcudeReturn) {
        erpProcudeReturn.setApproveStatus(1);
        // 根据采购退换货id删除明细
        erpReturnDetailsMapper.deleteByReturnId(erpProcudeReturn.getProcudeReturnId());
        // 新增销售退还单明细
        batchReturnDetails(erpProcudeReturn);
        return erpProcudeReturnMapper.updateErpProcudeReturn(erpProcudeReturn);
    }

    private void batchReturnDetails(ErpProcudeReturnDto erpProcudeReturn) {
        if (erpProcudeReturn.getDetailsList() != null && !erpProcudeReturn.getDetailsList().isEmpty()) {
            erpProcudeReturn.getDetailsList().forEach(item -> {
                item.setOrderId(erpProcudeReturn.getProcudeReturnId());
                item.setOrderOdd(erpProcudeReturn.getProcudeReturnOdd());
                item.setPayType(erpProcudeReturn.getPayType());
            });
            erpReturnDetailsMapper.batchReturnDetailsInsert(erpProcudeReturn.getDetailsList());
        }
    }

    @Override
    public int auditErpProcudeReturn(ErpProcudeReturn erpProcudeReturn) {
        ErpProcudeReturnVo procudeReturn = erpProcudeReturnMapper.selectErpProcudeReturnByProcudeReturnId(erpProcudeReturn.getProcudeReturnId());
        if (procudeReturn != null) {
            procudeReturn.setApproveId(SecurityUtils.getUserId());
            procudeReturn.setApproveName(SecurityUtils.getUsername());
            procudeReturn.setApproveTime(DateUtils.getNowDate());
            procudeReturn.setApproveStatus(erpProcudeReturn.getApproveStatus());
            // 审核通过时 根据退货商品生成应付款单，退换商品生成应付款和应收款单
            if (procudeReturn.getApproveStatus() == 3) {
                // 查询采购单
                ErpProcure erpProcure = erpProcureMapper.selectErpProcureByProcureId(procudeReturn.getProcureId());
                // 存储退货商品信息
                List<ErpReturnDetailsVo> returnGoodsList = new ArrayList<>();
                // 存储退换商品信息
                List<ErpReturnDetailsVo> returnsList = new ArrayList<>();
                for (ErpReturnDetailsVo erpReturnDetails : procudeReturn.getDetailsList()) {
                    // 采购商品为退货时 或者退换时 生成应收款单
                    if (erpReturnDetails.getReturnCommodityType() == 1 && (erpReturnDetails.getReturnType() == 1 || erpReturnDetails.getReturnType() == 2)) {
                        // 过滤出采购退换明细中的退换货商品
                        returnGoodsList = procudeReturn.getDetailsList().stream().filter(n -> n.getReturnCommodityType() == 1).collect(Collectors.toList());
                    }
                    // 采购单为退换时 生成应付款单
                    if (erpReturnDetails.getReturnCommodityType() == 2) {
                        // 过滤出采购退换明细中的换货商品
                        returnsList = procudeReturn.getDetailsList().stream()
                                .filter(n -> n.getReturnCommodityType() == 2).collect(Collectors.toList());
                    }
                }
                // 新增应收账款
                if (!returnGoodsList.isEmpty()) {
                    // 计算应收金额
                    BigDecimal oddSumMoney = new BigDecimal("0.0");
                    for (ErpReturnDetailsVo erpReturnDetailsVo : returnGoodsList) {
                        oddSumMoney = oddSumMoney.add((null == erpReturnDetailsVo.getProcurePrice() ? erpReturnDetailsVo.getCostPrice() : erpReturnDetailsVo.getProcurePrice()).multiply(BigDecimal.valueOf(erpReturnDetailsVo.getCommodityNumber())));
                    }
                    ErpAccountsReceivable erpAccountsReceivable = getErpAccountsReceivable(procudeReturn, erpProcure, oddSumMoney);
                    erpAccountsReceivableMapper.insertErpAccountsReceivable(erpAccountsReceivable);
                    // 计算应出库总量
                    int answerScheduledReceipt = (int) returnGoodsList.stream().mapToDouble(ErpReturnDetails::getCommodityNumber).sum();
                    // 取出仓库id 退换货类型为采购单时 因商品入库都是同一个库 则默认取出第一条仓库id即刻
                    Long wareId = procudeReturn.getWareId();
                    // 销售出库单字段赋值
                    ErpOutbound erpOutbound = ProcureSaleUtils.setOutboundFields(erpAccountsReceivable, wareId, answerScheduledReceipt);
                    erpOutboundMapper.insertErpOutbound(erpOutbound);
                    // 采购退换货单  退还商品  生成  出库明细
                    List<ErpOutboundDetails> erpOutboundDetailsList = ProcureSaleUtils.getErpOutboundDetailsByProcudeReturn(returnGoodsList, erpOutbound);
                    if (!erpOutboundDetailsList.isEmpty()) {
                        erpOutboundMapper.batchOutboundDetailsInsert(erpOutboundDetailsList);
                    }
                }
                // 新增应付账款
                if(!returnsList.isEmpty()){
                    // 计算应收金额
                    BigDecimal oddSumMoney = new BigDecimal("0.0");
                    for (ErpReturnDetailsVo erpReturnDetailsVo : returnsList) {
                        oddSumMoney = oddSumMoney.add(erpReturnDetailsVo.getCostPrice().multiply(BigDecimal.valueOf(erpReturnDetailsVo.getCommodityNumber())));
                    }
                    ErpAccountsPayable erpAccountsPayable = getErpAccountsPayable(procudeReturn, erpProcure, oddSumMoney);
                    erpAccountsPayableMapper.insertErpAccountsPayable(erpAccountsPayable);
                    // 计算应入库总量
                    int answerScheduledReceipt = (int) returnsList
                            .stream()
                            .mapToDouble(ErpReturnDetails::getCommodityNumber)
                            .sum();
                    // 取出仓库id 换货商品取采购退换货选中的仓库id
                    Long wareId = procudeReturn.getWareId();
                    // 销售出库单字段赋值
                    ErpWarehousing erpWarehousing = ProcureSaleUtils.setWarehousingFields(erpAccountsPayable, wareId, answerScheduledReceipt);
                    erpWarehousingMapper.insertErpWarehousing(erpWarehousing);
                    // 采购退换货单  退换商品  生成  入库明细
                    List<ErpWarehousingDetails> erpWarehousingDetailsList = ProcureSaleUtils.getErpWarehousingDetailsByProcudeReturn(returnsList, erpWarehousing);
                    if (!erpWarehousingDetailsList.isEmpty()) {
                        erpWarehousingMapper.batchWarehousingDetailsInsert(erpWarehousingDetailsList);
                    }
                }
            } else {
                procudeReturn.setRejectReason(erpProcudeReturn.getRejectReason());
                procudeReturn.setRejectTime(DateUtils.getNowDate());
            }
        }
        return erpProcudeReturnMapper.updateErpProcudeReturn(procudeReturn);
    }

    /**
     * 批量删除采购退换货
     *
     * @param procudeReturnIds 需要删除的采购退换货主键
     * @return 结果
     */
    @Override
    public int deleteErpProcudeReturnByProcudeReturnIds(Long[] procudeReturnIds) {
        return erpProcudeReturnMapper.deleteErpProcudeReturnByProcudeReturnIds(procudeReturnIds);
    }

    /**
     * 删除采购退换货信息
     *
     * @param procudeReturnId 采购退换货主键
     * @return 结果
     */
    @Override
    public int deleteErpProcudeReturnByProcudeReturnId(Long procudeReturnId) {
        return erpProcudeReturnMapper.deleteErpProcudeReturnByProcudeReturnId(procudeReturnId);
    }
}
